import type { VNodeChild } from "vue";
import { computed, defineComponent, reactive, ref, watch } from "vue";
import { $t } from "@/plugins/i18n";
import { useLayoutStore } from "@/stores/layout";
import { useRenderIcon } from "../hooks";
import IconifyIcon from "../iconifyIcon";
import { IconJson } from "./data";

type IconClassKeys = keyof typeof IconJson;

interface Props {
    modelValue: string | undefined | null;
}

export default defineComponent((props: Props, { emit }) => {
    /** 是否是移动端 */
    const isMobile = computed(() => useLayoutStore().device === "mobile");

    /** 搜索的图标名称 */
    const searchName = ref("");

    /** 选中的图标名称 */
    const iconValue = ref<string>(props.modelValue || "");

    /** 点击选择图标 */
    function handleClickIcon(icon: string): void {
        iconValue.value = `${currentTab.value}:${icon}`;
        emit("update:modelValue", iconValue.value);
    }

    /** 当前显示的图标 */
    const currentIcon = computed(() => {
        return iconValue.value ? useRenderIcon(`${iconValue.value}`) : useRenderIcon("ep:search");
    });

    // tab 切换
    const tabNames: Array<IconClassKeys> = Object.keys(IconJson) as any;
    const currentTab = ref(tabNames[0]);

    /** 分页相关（每个 tab 独立页码） */
    const pageSize = ref(40); // 每页图标数量
    const tabPageMap = reactive<Record<string, number>>({});
    tabNames.forEach((n) => {
        if (!tabPageMap[n]) {
            tabPageMap[n] = 1;
        }
    });

    // 切换 tab 时如果新 tab 未初始化页码则设为 1
    watch(currentTab, (n) => {
        if (!tabPageMap[n]) {
            tabPageMap[n] = 1;
        }
    });
    // 搜索条件变化时所有 tab 回到第一页，避免因结果减少造成越界
    watch(searchName, () => {
        tabNames.forEach((n) => {
            tabPageMap[n] = 1;
        });
    });

    /** 图标列表元素（分页） */
    const iconListElement = (name: IconClassKeys): VNodeChild => {
        const currentPage = tabPageMap[name] || 1;
        const keyword = searchName.value.trim();
        const filtered = IconJson[name].filter(icon => !keyword || icon.includes(keyword));
        const total = filtered.length;

        // 无搜索结果时展示空
        if (total === 0) {
            return (
                <div class="py-6">
                    <el-empty image-size={60} description={$t("status.noData")} />
                </div>
            );
        }

        const maxPage = Math.max(1, Math.ceil(total / pageSize.value));
        // 如果搜索后页数减少导致当前页越界，回退
        if (currentPage > maxPage) tabPageMap[name] = maxPage;
        const start = (tabPageMap[name] - 1) * pageSize.value;
        const pageIcons = filtered.slice(start, start + pageSize.value);

        return (
            <div>
                <div class={`grid gap-2 ${isMobile.value ? "grid-cols-5" : "grid-cols-8"}`}>
                    {pageIcons.map(icon => (
                        <div
                            class={` flex-center py-1 border border-solid border-[var(--el-border-color-light)] rounded cursor-pointer hover:bg-[var(--el-bg-color-light)] ${iconValue.value === icon ? "bg-[var(--el-bg-color-light)]" : ""}`}
                            onClick={() => handleClickIcon(icon)}
                            title={icon}
                            key={icon}
                        >
                            <IconifyIcon icon={`${currentTab.value}:${icon}`} class="text-2xl" />
                        </div>
                    ))}
                </div>
                <div class="flex justify-end mt-3">
                    <el-pagination
                        small
                        background
                        layout={isMobile.value ? "prev, next" : "prev, pager, next"}
                        pager-count={5}
                        total={total}
                        pageSize={pageSize.value}
                        currentPage={tabPageMap[name]}
                        onCurrentChange={(p: number) => { tabPageMap[name] = p; }}
                    />
                </div>
            </div>
        );
    };

    /** 清空已选择的图标 */
    function handleClear(): void {
        if (!iconValue.value) return;
        iconValue.value = "";
        emit("update:modelValue", "");
    }

    return () => (
        <div>
            <el-input
                modelValue={iconValue.value}
                placeholder={$t("placeholder.selectClickRightIcon")}
                clearable
                onClear={handleClear}
            >
                {{
                    prepend: () => (
                        <el-popover placement="right" trigger="click" popper-class={isMobile.value ? "w-[220px]!" : "w-[360px]!"}>
                            {{
                                reference: () => (
                                    <el-button
                                        class="w-16"
                                        icon={currentIcon.value}
                                    />
                                ),
                                default: () => (
                                    <div class="w-full">
                                        <el-input
                                            placeholder={$t("placeholder.inputName")}
                                            modelValue={searchName.value}
                                            onUpdate:modelValue={(value: string) => { searchName.value = value; }}
                                        />
                                        <el-tabs
                                            modelValue={currentTab.value}
                                            onTabChange={(tab: IconClassKeys) => { currentTab.value = tab; }}
                                            stretch
                                        >
                                            {tabNames.map(name => (
                                                <el-tab-pane label={name} name={name} key={name}>
                                                    {iconListElement(name)}
                                                </el-tab-pane>
                                            ))}
                                        </el-tabs>
                                    </div>
                                ),
                            }}
                        </el-popover>
                    ),
                }}
            </el-input>

        </div>
    );
}, {
    name: "IconSelect",
    props: {
        modelValue: {
            type: String,
            default: "",
        },
    },
    emits: ["update:modelValue"],
});
